/*
 * datastructures.h
 *
 *  Created on: Sep 26, 2013
 *      Author: cinus
 */

#ifndef DATASTRUCTURES_H_
#define DATASTRUCTURES_H_
#include <stdlib.h>
#include <stddef.h>

#include "types.h"
#include "settings.h"


struct netdata;
struct neuron;

typedef float32 (*afp)(struct netdata*, float32 x);
typedef void (*cdw)(struct netdata* net, struct neuron* self);

struct neuron {

	float32 z; //output
	float32 a; //sum of inputs
	float32 delta;
	//float32 gradient;

	float32* gradient;
	float32* gradientP;
	float32* deltaWeights;
	float32* deltaWeightsP;
	float32* ipropDelta;
	float32* ipropDeltaP;
	float32* weights; //outgoing weights

	afp activationFunction; //typedef is not yet known
	afp diffActivationFunction;

	uint32 n_input;
	uint32 n_output;

	struct neuron** inputs;
	struct neuron** outputs;

	uint32 layer; //used by the copy algorithm
	uint32 pos; //used by the copy algorithm
};

typedef struct neuron neuron_t;
typedef neuron_t* neuron_tp;

struct netdata {
	uint32 layersize;
	uint32 *neurons;
	uint32 colums;
	neuron_tp neuron_matrix;
	settings_t settings;
	float32 error;
	float32 lastError;
	float32 (*errorComputation)(float32 *output, float32 *target, size_t size);
	cdw computeDeltaWeights;

};

typedef struct netdata netdata_t;

typedef netdata_t* netdata_tp;

/**
 * Create a new network  with the specified settings
 */
netdata_t* initNetwork(const int8* settingsFileName);
void destroyNetwork(netdata_tp net);

/**
 * Save the net weights to a file
 */
void save(netdata_tp net, int8* fileName);
/**
 * Restores the weights from a file, the net has to be created first with initNetwork
 */
void load(netdata_tp net, int8* fileName);

//////////////////////////////////////////////////////////
// FUNCTION WHICH SHOULD NOT BE USED BY THE USERS
/////////////////////////////////////////////////////////$
netdata_tp initFullyConnectedNetwork(uint32 inputs, uint32 hidden, uint32 output, float32 (*huaf)(netdata_tp, float32 x), float32 (*dhuaf)(netdata_tp, float32 x), float32 (*ouaf)(netdata_tp, float32 x), float32 (*douaf)(netdata_tp, float32 x), float32 (*errorComputation)(float32 *output, float32 *target, size_t size), settings_tp settings);

neuron_t* getNeuron(netdata_t* net, uint32 i, uint32 j);
void debugMatrix(netdata_t* net);
void reserveNetSpace(netdata_tp originalNet, netdata_tp newNet);
void copy(netdata_tp src, netdata_tp dst);
void copyNeuron(neuron_tp src, neuron_tp dst, netdata_tp dstNet);
#endif /* DATASTRUCTURES_H_ */
